package com.bookbuf.api.exceptions;

import java.lang.reflect.Field;

/**
 * author: robert.
 * date :  16/8/2.
 */
public class PuDongException extends RuntimeException implements PuDongCode {

    private int statusCode;
    private Field field;
    private Exception exception;

    public PuDongException(int statusCode) {
        this.statusCode = statusCode;
    }

    public PuDongException(Exception e, Field field, int statusCode) {
        this.exception = e;
        this.statusCode = statusCode;
        this.field = field;
    }

    private static String getCause(int statusCode) {
        String cause;
        switch (statusCode) {
            case NOT_MODIFIED:
                cause = "There was no new data to return.";
                break;
            case BAD_REQUEST:
                cause = "The request was invalid. An accompanying error message will explain why. This is the status code will be returned during version 1.0 rate limiting(https://dev.twitter.com/pages/rate-limiting). In B v1.1, a request without authentication is considered invalid and you will get this response.";
                break;
            case UNAUTHORIZED:
                cause = "Authentication credentials were missing or incorrect. Ensure that you have set valid consumer key/secret, access token/secret, and the system clock is in sync.";
                break;
            case FORBIDDEN:
                cause = "The request is understood, but it has been refused. An accompanying error message will explain why. This code is used when requests are being denied due to update limits (https://support.twitter.com/articles/15364-about-twitter-limits-update-api-dm-and-following).";
                break;
            case NOT_FOUND:
                cause = "The URI requested is invalid or the resource requested, such as a user, does not exists. Also returned when the requested format is not supported by the requested method.";
                break;
            case NOT_ACCEPTABLE:
                cause = "Returned by the Search B when an invalid format is specified in the request.\n" +
                        "Returned by the Streaming B when one or more of the parameters are not suitable for the resource. The track parameter, for example, would throw this error if:\n" +
                        " The track keyword is too long or too short.\n" +
                        " The bounding box specified is invalid.\n" +
                        " No predicates defined for filtered resource, for example, neither track nor follow parameter defined.\n" +
                        " Follow userid cannot be read.";
                break;
            case ENHANCE_YOUR_CLAIM:
                cause = "Returned by the Search and Trends B when you are being rate limited.\n"
                        + "Returned by the Streaming B:\n Too many login attempts in a short period of time.\n" +
                        " Running too many copies of the same application authenticating with the same account name.";
                break;
            case UNPROCESSABLE_ENTITY:
                cause = "Returned when an image uploaded to POST account/update_profile_banner is unable to be processed.";
                break;
            case TOO_MANY_REQUESTS:
                cause = "Returned in B v1.1 when a request cannot be served due to the application's rate limit having been exhausted for the resource. See Rate Limiting in B v1.1.(https://dev.twitter.com/docs/rate-limiting/1.1)";
                break;
            case INTERNAL_SERVER_ERROR:
                cause = "Something is broken.";
                break;
            case BAD_GATEWAY:
                cause = "BusinessApiImpl is down or being upgraded.";
                break;
            case SERVICE_UNAVAILABLE:
                cause = "The BusinessApiImpl servers are up, but overloaded with requests. Try again later.";
                break;
            case GATEWAY_TIMEOUT:
                cause = "The BusinessApiImpl servers are up, but the request couldn't be serviced due to some failure within our stack. Try again later.";
                break;
            default:
                cause = "";
        }
        return statusCode + ":" + cause;
    }

    @Override
    public String getMessage() {
        StringBuilder value = new StringBuilder();
        if (field != null) {
            value.append("[fieldName = ");
            value.append(field.getName());
            value.append("]");
        }
        if (exception != null) {
            value.append(exception.getCause());
            value.append(":");
            value.append(exception.getMessage());
        }
        if (super.getMessage() != null) {
            value.append(super.getMessage());
        }
        if (statusCode != -1) {
            return getCause(statusCode) + "\n" + value.toString();
        } else {
            return value.toString();
        }
    }
}
